structure Intl :> INTL =
struct
  datatype t
    = T of {value : int}
  
  fun abs (T {value}) = 
      T {value = Int.abs value}
  
  fun bogus () = T {value = 0}

  fun compare (T {value = k1}, T {value = k2}) = Int.compare (k1, k2)
  
  fun equals (T {value = k1}, T {value = k2}) = (k1 = k2)

  fun fromInt i = T {value = i}
  
  fun fromString s =
      let val value = Int.fromString s
                      handle Overflow => raise Fail "integer is too large : fromString\n"
      in  case value
           of SOME v => T {value = v}
            | NONE => raise Fail "no called on legal string : fromString\n"
      end
      
  fun isZero (T {value}) = value = 0
      
  fun println (T {value}) = print (String.concat [Int.toString value, "\n"])
  
  fun toInt (T {value}) = value
    
  fun toString (T {value}) = Int.toString value
  
  fun toString2 (T {value}) = 
      if value >= 0 
      then Int.toString value
      else "-"^(Int.toString (Int.abs value))
  
  val zero = fromInt 0
  
  fun gt (T {value = v1}, T {value = v2}) = v1 > v2
  fun ge (T {value = v1}, T {value = v2}) = v1 >= v2
  fun lt (T {value = v1}, T {value = v2}) = v1 < v2
  fun le (T {value = v1}, T {value = v2}) = v1 <= v2
  fun ne (T {value = v1}, T {value = v2}) = v1 <> v2
  
  fun plus (T {value = v1}, T {value = v2}) =
      T {value = v1 + v2} handle Overflow => raise Fail "integer too large\n"
  
  fun minus (T {value = v1}, T {value = v2}) =
      T {value = v1 - v2} handle Overflow => raise Fail "integer too large\n"
      
  fun times (T {value = v1}, T {value = v2}) = 
      T {value = v1 * v2} handle Overflow => raise Fail "integer too large\n"
      
  fun divide (T {value = v1}, T {value = v2}) =
      T {value = op div (v1, v2)}
      handle Overflow => raise Fail "overflow in : div\n"
      | Div => raise Fail "divided by 0\n"
      
  fun modus (T {value = v1}, T {value = v2}) =
      T {value = v1 mod v2} handle Div => raise Fail "divided by 0\n"
end
